/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-04-27
*/
package com.rzico.account.service;

import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.*;
import com.rzico.account.mapper.DepositMapper;
import com.rzico.account.mapper.PaymentMapper;
import com.rzico.account.mapper.TransferMapper;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.account.mapper.PointMapper;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.entity.Member;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.basics.service.MsgService;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.entity.SysUser;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.core.plugin.TransferPlugin;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysPluginService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <pre>
 * 金币账单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class PointService extends BaseServiceImpl<Point, String> {

    @Autowired
    private PointMapper pointMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private DepositMapper depositMapper;

    @Autowired
    private RefundsService refundsService;

    @Autowired
    private PaymentService paymentService;

    @Autowired @Lazy
    private MsgService msgService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired @Lazy
    private TransferMapper transferMapper;

    @Autowired @Lazy
    private TransferService transferService;

    @Override
    public BaseMapper<Point, String> getMapper() {
        return pointMapper;
    }

    //付款
    @Transactional(rollbackFor = Exception.class)
    public void payment(Payment payment) {

        if (!payment.getStatus().equals(Payment.STATUS_WAITING)) {
            throw new CustomException("不是待付款状态");
        }

        payment.setStatus(Payment.STATUS_SUCCESS);
        payment.setPaymentDate(new Date());
        payment.setPaymentPluginId("pointPayPlugin");
        payment.setPaymentPluginName("金币");
        paymentService.updateByPrimaryKeySelective(payment);

        Long value = payment.getAmount().multiply(new BigDecimal(100)).setScale(0).longValue();

        Member member = memberMapper.selectByPrimaryKey(payment.getMemberId());
        if (member.calculateAvailablePoint()<value) {
            throw new CustomException("可用金币不足");
        }

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",payment.getMemberId());
        updateParams.put("value",value);
        memberMapper.decPoint(updateParams);

        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(payment.getMemberId());
        if (member.getPoint()<0L) {
            throw new CustomException("可用金币不足");
        }

        Point point = new Point();
        point.setBalance(member.getPoint());
        point.setDebit(value);
        point.setCredit(0L);
        point.setCreateDate(new Date());
        point.setDeleted(false);
        point.setEnterpriseId(payment.getEnterpriseId());
        point.setMemberId(payment.getMemberId());
        point.setMemo(payment.getMemo());
        point.setPaymentId(payment.getId());
        point.setType(1);
        point.setDeleted(false);
        point.setOrderId(payment.getOrderId());
        point.setOrderType(payment.getOrderType());
        super.insertUseGeneratedKeys(point);

        Map<String,Object> content = new HashMap<>();

        content.put("title", "付款成功-金币");

        content.put("memo",payment.getMemo());
        content.put("amount",payment.getAmount());
        content.put("balance",point.getBalance());
        content.put("type",3);
        msgService.sendNotity(member,"msg-account",content.get("title").toString(), JSON.toJSONString(content),null);


    }

    //退款
    @Transactional(rollbackFor = Exception.class)
    public void refunds(Refunds refunds) {
        if (!refunds.getStatus().equals(Refunds.STATUS_WAITING)) {
            throw new CustomException("不是待退款状态");
        }
        refunds.setStatus(Refunds.STATUS_REFUNDED);
        refunds.setRefundsDate(new Date());
        refunds.setPaymentPluginId("pointPayPlugin");
        refunds.setPaymentPluginName("金币");
        refundsService.updateByPrimaryKeySelective(refunds);

        Long value = refunds.getAmount().multiply(new BigDecimal(100)).setScale(0).longValue();

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",refunds.getMemberId());
        updateParams.put("value",value);
        memberMapper.addPoint(updateParams);

        //更新重新读取余额
        Member member =  memberMapper.selectByPrimaryKey(refunds.getMemberId());

        Point point = new Point();
        point.setBalance(member.getPoint());
        point.setDebit(0L);
        point.setCredit(value);
        point.setCreateDate(new Date());
        point.setDeleted(false);
        point.setEnterpriseId(refunds.getEnterpriseId());
        point.setMemberId(refunds.getMemberId());
        point.setMemo(refunds.getMemo());
        point.setPaymentId(refunds.getId());
        point.setType(2);
        point.setDeleted(false);
        point.setOrderId(refunds.getOrderId());
        point.setOrderType(refunds.getOrderType());
        super.insertUseGeneratedKeys(point);

        Map<String,Object> content = new HashMap<>();

        content.put("title", "退款成功-金币");

        content.put("memo",refunds.getMemo());
        content.put("amount",refunds.getAmount());
        content.put("balance",point.getBalance());
        content.put("type",3);
        msgService.sendNotity(member,"msg-account",content.get("title").toString(), JSON.toJSONString(content),null);


    }

    //收入
    @Transactional(rollbackFor = Exception.class)
    public void addPoint(Long memberId,Long value,String memo,Integer orderType,Long orderId) {

        Member member = memberMapper.selectByPrimaryKey(memberId);

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.addPoint(updateParams);

        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(memberId);

        Point point = new Point();
        point.setBalance(member.getPoint());
        point.setDebit(0L);
        point.setCredit(value);
        point.setCreateDate(new Date());
        point.setDeleted(false);
        point.setEnterpriseId(member.getEnterpriseId());
        point.setMemberId(memberId);
        point.setMemo(memo);
        point.setType(0);
        point.setDeleted(false);
        point.setOrderType(orderType);
        point.setOrderId(orderId);
        super.insertUseGeneratedKeys(point);

    }

    //支出
    @Transactional(rollbackFor = Exception.class)
    public void decPoint(Long memberId,Long value,String memo,Integer orderType,Long orderId) {

        Member member = memberMapper.selectByPrimaryKey(memberId);

        if (member.getPoint()<value) {
            throw new CustomException("金币余额不足");
        }

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.decPoint(updateParams);

        //更新重新读取余额
        member = memberMapper.selectByPrimaryKey(memberId);

        if (member.getPoint()<0) {
            throw new CustomException("金币余额不足");
        }

        Point point = new Point();
        point.setBalance(member.getPoint());
        point.setDebit(0L);
        point.setCredit(0L-value);
        point.setCreateDate(new Date());
        point.setDeleted(false);
        point.setEnterpriseId(member.getEnterpriseId());
        point.setMemberId(memberId);
        point.setMemo(memo);
        point.setType(0);
        point.setDeleted(false);
        point.setOrderType(orderType);
        point.setOrderId(orderId);
        super.insertUseGeneratedKeys(point);

    }

    @Transactional(rollbackFor = Exception.class)
    public void addFreezePoint(Long memberId,Long value) {

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.addFreezePoint(updateParams);

    }

    @Transactional(rollbackFor = Exception.class)
    public void decFreezePoint(Long memberId,Long value) {

        Map<String,Object> updateParams = new HashMap<>();
        updateParams.put("id",memberId);
        updateParams.put("value",value);
        memberMapper.decFreezePoint(updateParams);

    }


    public BigDecimal calculate(Enterprise enterprise,BigDecimal amount) {
        return BigDecimal.ZERO;
    }

    //提现
    @Transactional(rollbackFor = Exception.class)
    public Point transfer(Member member,BigDecimal amount,String paymentPluginId,String sn) {


        Enterprise enterprise = enterpriseService.selectByPrimaryKey(member.getEnterpriseId());
        BigDecimal fee = calculate(enterprise,amount);

        Long value = amount.multiply(new BigDecimal(100)).longValue();

        if (member.calculateAvailablePoint()<value) {
            throw new CustomException("可提现金币不足");
        }

        Map<String,Object> params = new HashMap<>();
        params.put("id",member.getId());
        params.put("value",value);
        memberMapper.decPoint(params);

        member = memberMapper.selectByPrimaryKey(member.getId());

        if (member.getPoint()<0) {
            throw new CustomException("可提现金币不足");
        }

        Point point = new Point();
        point.setBalance(member.getPoint());
        point.setDebit(value);
        point.setCredit(0L);
        point.setCreateDate(new Date());
        point.setDeleted(false);
        point.setEnterpriseId(member.getEnterpriseId());
        point.setMemberId(member.getId());
        point.setMemo("提现到微信零钱");
        point.setType(3);
        point.setDeleted(false);
        point.setOrderType(0);
        point.setOrderId(null);
        super.insertUseGeneratedKeys(point);

        //生成付款单
        Transfer transfer = new Transfer();
        transfer.setMemberId(member.getId());
        transfer.setSn(sn);
        transfer.setAmount(amount);
        transfer.setFee(fee);
        transfer.setCreateDate(new Date());
        transfer.setModifyDate(transfer.getCreateDate());
        transfer.setDeleted(false);
        transfer.setPaymentPluginId(paymentPluginId);
        transfer.setPaymentPluginName("付款到微信零钱");

        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {
            //特约商户,服务商代收 status
            enterprise = enterpriseService.findByMch(sysMch.getIsvId());
        }

        transfer.setEnterpriseId(enterprise.getId());
        transfer.setMemo("提现到微信零钱");
        transfer.setStatus(0);
        transfer.setType(3);
        transferMapper.insertUseGeneratedKeys(transfer);


        if (sysMch.getMchType().equals(2)) {
            //特约商户，用户提现扣商家钱
            Member shopMember = memberMapper.selectByPrimaryKey(enterprise.getMemberId());

            params.clear();
            params.put("id",shopMember.getId());
            params.put("value",transfer.getAmount());
            memberMapper.decBalance(params);

            shopMember = memberMapper.selectByPrimaryKey(shopMember.getId());

            Deposit shopDeposit = new Deposit();
            shopDeposit.setCreateDate(new Date());
            shopDeposit.setModifyDate(new Date());
            shopDeposit.setBalance(shopMember.getBalance());
            shopDeposit.setDebit(transfer.getAmount());
            shopDeposit.setCredit(BigDecimal.ZERO);
            shopDeposit.setDeleted(false);
            shopDeposit.setEnterpriseId(shopMember.getEnterpriseId());
            shopDeposit.setMemberId(shopMember.getId());
            shopDeposit.setMemo("会员提现-"+transfer.getMemo());
            shopDeposit.setType(3);
            shopDeposit.setDeleted(false);
            depositMapper.insertUseGeneratedKeys(shopDeposit);
        }

        //微信零钱秒到，自动发起付款申请
        if ("weixinWalletPlugin".equals(paymentPluginId)) {
            transferService.submit(transfer,paymentPluginId);
        }

        return point;

    }


}
